<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <script type="text/javascript" src='../jquery-1.11.1.js'></script>

</head>
<body>

<style>

</style>
<style>
  
  </style>

<div  onclick="updateImg()">上传</div>
<img src="" id="yulan">


<script type="text/javascript">


function updateImg(){
      
      jsUploadImage({"diyparam":"1111","diyparam1":"222","previewImgId":"yulan","url":"user.php?act=photosave","success":function(data){
          console.log(data);
      }})
 };



 /** 
* js使用form上传图片，支持本地预览选中的图片,支持携带自定义参数
* @param {string}    params.previewImgId      预览图片控件id,可以预览上传图片
* @param {string}    params.url               提交上传的url
* @param {function}  params.success           上传接口的回调函数
* @param {boolean}   params.params            上传时提交的其它参数 有几个传几个，系统会把 previewImgId  url success 这三个参数过滤后的其它参数传给服务器
  使用示例：
  <img src="" id="yulan">
  <div id="shangchuan">上传</div>
 document.createElement("shangchuan").click = function(){
        jsUploadImage({"diyparam":"1111","diyparam1":"222","previewImgId":"yulan","url":"user.php?act=photosave","success":function(data){
            console.log(data);
        }})
   };
*/
function jsUploadImage(params){   
    //初始化数据
    params.previewImgId = params.previewImgId || "";
    params.url = params.url || "";
    params.success = params.success || "";

    //创建file上传控件 
    if(document.getElementById("imgFile")==null){
         var  inputEle=document.createElement("input"); //创建input  
         inputEle.id="imgFile";  
         inputEle.type="file"; 
         inputEle.accept="image/png,image/jpeg,image/jpeg,DCIM/*;capture=camera"; 
         inputEle.style="display:none;"; 
         inputEle.onchange = function(){
             showPhoto()
         };
         inputEle.multiple = false;
         document.body.appendChild(inputEle);          
    }
    var  imgFile = document.getElementById("imgFile"); 
    imgFile.click();
     
     
    //选中文件后的预览图片
    function showPhoto(){
        //文件对象  
        var file = document.getElementById("imgFile").files[0];
        
        //读取后辍,判断是否允许的文件
        var fileSuffix = file.name.substring(file.name.length-4);
        var allowFile = ".jpg|.png|.gif";
        if(allowFile.indexOf(fileSuffix.toLowerCase())==-1) {
            alert("请使用"+allowFile+"后辍的文件");
            return false;
        }
        
        //如果传了显示控件的id,显示本地预览
        var reader = new FileReader()
        reader.readAsDataURL(file);
        reader.onload = function(e){ 
            var imgBase64Data = e.target.result;
            var imgtype = file.type;
            //显示预览
           //if("" !=  params.previewImgId)  document.getElementById(params.previewImgId).src = imgBase64Data;
           
           //如果不压缩直接上传 
           //savePhoto(imgBase64Data)
           
            //对图片进行缩小处理,然后再上传
            compressPhoto(imgBase64Data,100,100,imgtype,function(imgBase64DataBack){
			    //显示预览 压缩后的
			    if("" !=  params.previewImgId)  document.getElementById(params.previewImgId).src = imgBase64DataBack;
			
			    //console.log("===压缩后数据===");    
				//var imgBase64DataBack = imgBase64DataBack; //Base64数据，可以直接放在img上  img.src = imgBase64DataBack   
				//var blob = dataURLtoBlob(imgBase64DataBack);   //blob对象, Base64转blob 对象  
				//var blobUrl = getObjectURL(blob);    //blob url,利用 blob对象创建URL 直接可以赋值到img 比如用在 img.src = blobUrl                           
				//console.log(imgBase64DataBack);                   
				//console.log(blob);
				//console.log(blobUrl);
    			
                //提交服务保存数据
                savePhoto(imgBase64DataBack)
            });  
            
        }        
        
    }
    
    //提交数据
    function savePhoto(base64Data){
        var formData = new FormData(); 
        
        //加入其它参数
        for(var key in params){
          if(key!="previewImgId" && key!="url" && key!="success" ){
              formData.append(key, params[key]);
          }
        }        
        //加入文件参数  利用base64
        formData.append("imgFile",encodeURIComponent(base64Data));
        //加入文件参数  file控件上传 , 但这种试就不支持对图片压缩了，所以手机端不采用这种方式
        //formData.append('imgFile', file);
        
        //ajax上传
        $.ajax({
            url:params.url,
            type: 'POST',
            cache: false,
            dataType:"json",
            data: formData,
            processData: false,
            contentType: false
        }).success(function(res) {
            if(params.success!=""){
                params.success(res);
            }
        }).fail(function(res) {
           alert("上传失败");
        });
    }

}
   
/** 
* js利用canvas对图像进行压缩处理
* @param {string}    imgBase64Data     图像base64数据
* @param {string}    maxWidth          最大高度
* @param {function}  maxHeight         最大宽度
* @param {boolean}   fun               回调函数，参数为处理后的图像数据
  使用示例：
  compressPhoto(imgBase64Data,maxWidth,maxHeight,imgtype,function(imgBase64Data){
      //返回图片数据后的处理
  })
*/
function compressPhoto(imgBase64Data,maxWidth,maxHeight,imageType,fun){
    var  img = new Image();

    // 缩放图片需要的canvas
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');

    // base64地址图片加载完毕后
    img.onload = function () {
        // 图片原始尺寸
        var originWidth = this.width;
        var originHeight = this.height;            
        // 目标尺寸
        var targetWidth = originWidth, targetHeight = originHeight;
        // 图片尺寸超过400x400的限制
        if (originWidth > maxWidth || originHeight > maxHeight) {
            if (originWidth / originHeight > maxWidth / maxHeight) {
                // 更宽，按照宽度限定尺寸
                targetWidth = maxWidth;
                targetHeight = Math.round(maxWidth * (originHeight / originWidth));
            } else {
                targetHeight = maxHeight;
                targetWidth = Math.round(maxHeight * (originWidth / originHeight));
            }
        }

        // canvas对图片进行缩放
        canvas.width = targetWidth;
        canvas.height = targetHeight;
        // 清除画布
        context.clearRect(0, 0, targetWidth, targetHeight);
        // 图片压缩
        context.drawImage(img, 0, 0, targetWidth, targetHeight);

        var base=canvas.toDataURL(imageType ? imageType: "image/jpeg",0.7);//canvas转码为base64                
        fun(base);//返回处理 
    };

    img.src = imgBase64Data;
}

/** 
* base64图像数据转 Blob对像
* @param {string}    imgBase64Data     图像base64数据
* @return  {Blob}   Blob           

*/
function dataURLtoBlob(imgBase64Data) {
    var arr = imgBase64Data.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
}
//blob对象创建URL 直接可以赋值到img 比如用在 img.src = blobUrl
//file 可以是form中的file表单，也可以是blob对象
function getObjectURL(file) {
    var url = null;
    if (window.createObjectURL != undefined) { // basic
        url = window.createObjectURL(file);
    } else if (window.URL != undefined) { // mozilla(firefox)
        url = window.URL.createObjectURL(file);
    } else if (window.webkitURL != undefined) { // webkit or chrome
        url = window.webkitURL.createObjectURL(file);
    }
    return url;
};
//void append(DOMString name, Blob value, optional DOMString filename);void append(DOMString name, DOMString value);
//name  字段名称.
//value 字段值.可以是file blod对象,或者一个字符串,如果全都不是,则该值会被自动转换成字符串.
//filename  (可选) 指定文件的文件名,当value参数被指定为一个Blob对象或者一个File对象时,该文件名会被发送到服务器上,对于Blob对象来说,这个值默认为"blob".
//formdata.append("file", $(value).data("img"), new Date().getTime()+Math.random()*100+".jpg");
</script>
</body>
</html>


